package com.example;

import com.baomidou.dynamic.datasource.toolkit.CryptoUtils;
import com.baomidou.mybatisplus.core.toolkit.AES;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.mysql.entity.User;
import com.example.mysql.mapper.UserMapper;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Base64;

/**
 * Unit test for simple App.
 */
@SpringBootTest
public class AppTest {

    /**
     * mybatis-plus 加密测试
     * 参考官网  https://baomidou.com/guides/security/
     */
    @Test
    void mybatisPlusTest(){
        //加密配置必须以 mpw: 字符串开头。随机密钥应由负责人妥善保管，知晓的人越少越好。

        // 生成16位随机AES密钥
        String randomKey = AES.generateRandomKey();

        String url = "jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai";

        // 使用随机密钥加密数据
        String encryptedData = AES.encrypt(url, randomKey);
        System.out.println(encryptedData);

    }

    /**
     * dynamic-datasource 加密测试
     * 参考官网  https://www.kancloud.cn/tracy5546/dynamic-datasource/2280963
     */
    @Test
    void dynamicDatasourceTest() throws Exception {
        String password = "123456";
        // 使用默认的publicKey ，建议还是使用下面的自定义
        String encodePassword = CryptoUtils.encrypt(password);
        System.out.println(encodePassword);

        // 自定义publicKey
        String[] arr = CryptoUtils.genKeyPair(512);
        System.out.println("privateKey:  " + arr[0]);
        System.out.println("publicKey:  " + arr[1]);
        // 使用的是私钥加密，有点违反直觉
        // 建议更高的安全，可以把publicKey在启动时候传进去，或者配置中心配好，不让普通开发接触到就好。
        System.out.println("url:  " + CryptoUtils.encrypt(arr[0], "jdbc:mysql://127.0.0.1:3306/order"));
        System.out.println("username:  " + CryptoUtils.encrypt(arr[0], "root"));
        System.out.println("password:  " + CryptoUtils.encrypt(arr[0], "123456"));
    }


    @Resource
    private UserMapper userMapper;

    // 如果不喜欢写 xml 文件，可以尝试使用 join 插件
    // 官方网址 https://mybatis-plus-join.github.io/
    // github 项目地址 https://github.com/yulichang/mybatis-plus-join
    void testJoin() {
        // 和Mybatis plus一致，MPJLambdaWrapper的泛型必须是主表的泛型，并且要用主表的Mapper来调用
        MPJLambdaWrapper<User> wrapper = JoinWrappers.lambda(User.class)
                .selectAll(User.class) // 查询 user 表全部字段
                .select(UserAddressDO::getTel) // 查询 user_address tel 字段
                .selectAs(UserAddressDO::getAddress, UserDTO::getUserAddress) // 别名
                .select(AreaDO::getProvince, AreaDO::getCity)
                .leftJoin(UserAddressDO.class, UserAddressDO::getUserId, UserDO::getId)
                .leftJoin(AreaDO.class, AreaDO::getId, UserAddressDO::getAreaId)
                .eq(UserDO::getId, 1)
                .like(UserAddressDO::getTel, "1")
                .gt(UserDO::getId, 5);

        // 连表查询 返回自定义ResultType
        List<UserDTO> list = userMapper.selectJoinList(UserDTO.class, wrapper);

        // 分页查询 （需要启用 mybatis plus 分页插件）
        Page<UserDTO> listPage = userMapper.selectJoinPage(new Page<>(2, 10), UserDTO.class, wrapper);
    }

    /*
     * 对应 sql 语句
        SELECT
            t.id, t.name, t.sex, t.head_img,
            t1.tel, t1.address AS userAddress,
            t2.province, t2.city
        FROM
            user t
            LEFT JOIN user_address t1 ON t1.user_id = t.id
            LEFT JOIN area t2 ON t2.id = t1.area_id
        WHERE (
            t.id = ?
            AND t1.tel LIKE ?
            AND t.id > ?)
    */

}
